<?php

class BookController extends FrontController {

    public $staff_id = FALSE;
    public $start_time = FALSE;
    public $service = FALSE;
    public $user_id = FALSE;
    public $customer_id = FALSE;
    public $appt_id = FALSE;

    public function actionSecret() {
        define("DEBUG", 1);

        // Set to 0 once you're ready to go live
        define("USE_SANDBOX", 1);


        define("LOG_FILE", "./ipn.log");


// Read POST data
// reading posted data directly from $_POST causes serialization
// issues with array data in POST. Reading raw POST data from input stream instead.
        $raw_post_data = file_get_contents('php://input');
        $raw_post_array = explode('&', $raw_post_data);
        $myPost = array();
        foreach ($raw_post_array as $keyval) {
            $keyval = explode('=', $keyval);
            if (count($keyval) == 2)
                $myPost[$keyval[0]] = urldecode($keyval[1]);
        }
// read the post from PayPal system and add 'cmd'
        $req = 'cmd=_notify-validate';
        if (function_exists('get_magic_quotes_gpc')) {
            $get_magic_quotes_exists = true;
        }
        foreach ($myPost as $key => $value) {
            if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
                $value = urlencode(stripslashes($value));
            } else {
                $value = urlencode($value);
            }
            $req .= "&$key=$value";
        }

// Post IPN data back to PayPal to validate the IPN data is genuine
// Without this step anyone can fake IPN data

        if (USE_SANDBOX == true) {
            $paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
        } else {
            $paypal_url = "https://www.paypal.com/cgi-bin/webscr";
        }

        $ch = curl_init($paypal_url);
        if ($ch == FALSE) {
            return FALSE;
        }

        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);

        if (DEBUG == true) {
            curl_setopt($ch, CURLOPT_HEADER, 1);
            curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
        }

// CONFIG: Optional proxy configuration
//curl_setopt($ch, CURLOPT_PROXY, $proxy);
//curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
// Set TCP timeout to 30 seconds
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));

// CONFIG: Please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path
// of the certificate as shown below. Ensure the file is readable by the webserver.
// This is mandatory for some environments.
//$cert = __DIR__ . "./cacert.pem";
//curl_setopt($ch, CURLOPT_CAINFO, $cert);

        $res = curl_exec($ch);
        if (curl_errno($ch) != 0) { // cURL error
            if (DEBUG == true) {
                MyEmail::send_error('cUrl error paypal');
                error_log(date('[Y-m-d H:i e] ') . "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
            }
            curl_close($ch);
            exit;
        } else {
            // Log the entire HTTP response if debug is switched on.
            if (DEBUG == true) {
                error_log(date('[Y-m-d H:i e] ') . "HTTP request of validation request:" . curl_getinfo($ch, CURLINFO_HEADER_OUT) . " for IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
                error_log(date('[Y-m-d H:i e] ') . "HTTP response of validation request: $res" . PHP_EOL, 3, LOG_FILE);

                // Split response headers and payload
//                list($headers, $res) = explode("\r\n\r\n", $res, 2);
            }
            curl_close($ch);
        }


//        if(strpos($res, 'VERIFIED') !== FALSE){
        if (TRUE) {

            $appt_id = $_POST['item_number'];

            $appt_model = Appoint::model()->findByPk($appt_id);

            if ($appt_model) {

                $appt_model->status = Appoint::STATUS_COMPLETED_webmaster;

                if ($appt_model->save()) {
                    
                    //find service
                    $this->service = Service::getRecordbySid($appt_model->service_id);
                    
                    
                    try {
                        $data = PaypalPayment::model()->check_hot_deals_afterpaypal($appt_model->service_id, $appt_model->date, $appt_model->start_time);

                        $ft = $this->appt_is_1st($appt_id);

                        $hotdeal_discount = 0;
                        $price = 0.0;
                        
                        
                        if (!empty($data)) {
                            $hotdeal_discount = $data['discount'];
                            $this->hotdeal_discount=$hotdeal_discount;
                            $price = $data['price'];

                            $dis_count = number_format(($data['price'] * $data['discount']) / 100, 2);
                            $final_price = number_format($data['price'] - $dis_count, 2);
                            $dis_count = number_format($dis_count, 2) . ' (' . $data['discount'] . '%' . ')';
                        } else {
                            $price = $this->service->price;
                        }
                        if (NULL != $ft) {


                            $dis = $hotdeal_discount + $ft->discount;


                            $dis_count = number_format(($price * $dis) / 100, 2);


                            $final_price = number_format($price - $dis_count, 2);
                            
                            $this->discount_firsttime=$ft->discount;
                            
                        } 
                        
                        $this->appt_id = $appt_model->apt_id;
                        $this->biz_id = $appt_model->author->author->id;

                        $this->cus_ckey = $appt_model->aptCustomer->customer->ckey;
                        $this->hotdeal_discount = $hotdeal_discount;
                        $this->init_price = $this->service->price;
                        $this->total_price = isset($final_price) ? $final_price : $this->service->price;

                        try {
                            if ($this->process_order()) {
                                $this->process_receipt();
                            } 
                        } catch (Exception $ex) {
                        }


                        MyEmail::send_email_confirmed_to_customer($appt_model, $appt_model->aptCustomer->customer, FALSE, $dis_count, $final_price, array('order_key' => $this->order_key));
                        MyEmail::send_email_confirmed_to_merchant($appt_model, $appt_model->aptCustomer->customer, FALSE, $dis_count, $final_price);
                        MyEmail::send_email_confirmed_to_staff($appt_model, $appt_model->aptCustomer->customer, FALSE, $dis_count, $final_price);
                    } catch (Exception $ex) {
                        
                    }
                } else {
                    
                }
            } else {
                MyEmail::send_error('Cannot appoint apptid' . $appt_id);
            }
        }
    }

    public function appt_is_1st($id_appt) {
        return FirstTimeApt::model()->findByAttributes(array('appointment_id' => $id_appt));
    }

    /**
     *
     * @var boolean <b>TRUE</b> if appoinment is 1st 
     */
    public $is_1st = FALSE;
    public $discount_firsttime = 0;

    public function actionCreateAppt() {

        if (FALSE == $this->process_service()) {
            $this->echo_browser('err');
        }

        if (Customer::is_1st_with_current_user($this->service->user->ukey)) {
            $this->is_1st = TRUE;
            $this->create_appoinmnet();


            $first_time_discount = Thefirst::getDiscountByTime($this->service->sid, strtotime(str_replace('/', '-', $_POST['date'])), $this->start_time);

            if (FALSE != $first_time_discount) {

                $this->discount_firsttime = $first_time_discount;
                $this->hotdeal_discount+=$first_time_discount;
            }
        }

        $hotdeal_discount = Hotdeal::getDiscountByTime($this->service->sid, strtotime(str_replace('/', '-', $_POST['date'])), $this->start_time);

        if (FALSE != $hotdeal_discount) {
            $this->hotdeal_discount+=$hotdeal_discount;
        }
        if (FALSE == $this->process_user()) {
            $this->echo_browser('err');
        }

        $this->process_customer_merchant();

        if (FALSE == $this->customer_id) {
            $this->echo_browser('err');
        }

        $appt_id = $this->create_appoinmnet();


        //if create service error
        if (FALSE == $appt_id) {
            $this->echo_browser('err');
        }

        $this->process_apt_cus();


//        $this->process_order(); 

        if ($this->is_1st) {
            $this->process_1st();
        }


        echo json_encode(array(
            'status' => 'ok',
            'appt_id' => $this->appt_id,
        ));
        Yii::app()->end();
    }

    public function process_1st() {
        $ft = new FirstTimeApt();
        $ft->appointment_id = $this->appt_id;

        //temporari order_id=0
        // after payment, system will update order_id
        $ft->order_id = 0;
        $ft->discount = $this->discount_firsttime;

        if ($ft->validate() and $ft->save()) {
            return TRUE;
        } else {
            var_dump($ft->getErrors());
            die;
            return FALSE;
        }
    }

    public function process_apt_cus() {

        $appt = new AptCustomer();
        $appt->apt_id = $this->appt_id;
        $appt->customer_id = $this->customer_id;

        if ($appt->validate() and $appt->save()) {
            return TRUE;
        } else {
            return FALSE;
        }
    }

    /**
     * check customer with merchant
     */
    public function process_customer_merchant() {
        $cus = Customer::checkCustomerBelongToBiz($this->user_id, $this->service->author_id);

        if (FALSE != $cus) {
            $this->customer_id = $cus->id;
            $this->cus_ckey = $cus->ckey;
        } else {

            $this->process_customer();
        }
    }

    public function process_customer() {

        $cus = new Customer();
        $cus->user_id = $this->user_id;
        $cus->biz_id = $this->service->author_id;
        $cus->status = Customer::STATUS_ACTIVE;

        if ($cus->validate() AND $cus->save()) {

            $cus->updateCkey();
            $this->customer_id = $cus->id;
            $this->cus_ckey = $cus->ckey;
        } else {
            return FALSE;
        }
    }

    public function echo_browser($status, $appt = 1) {
        echo json_encode(array(
            'status' => $status,
            'appt_id' => $appt,
        ));
        Yii::app()->end();
    }

    /**
     * Process 
     */
    public function process_user() {

        $user = Users::check_exist_by_email($_POST['email'], Users::TYPE_CUSTOMER);

        if (FALSE == $user) {//not exist
            //create new user
            return $this->_process_user($user);
        } else {
            //update user
            return $this->_process_user($user, TRUE);
        }
    }

    public function _process_user($ip_user, $is_update = FALSE) {

        if (FALSE == $is_update) {
            $user = new Users();
        } else {
            $user = $ip_user;
        }

        $user->firstname = $_POST['fname'];
        $user->lastname = $_POST['lname'];
        $user->address = $_POST['address'];
        $user->postal_code = $_POST['postal_code'];
        $user->occupation = $_POST['occupation'];
        $user->mobile_phone = $_POST['phone'];
        $user->country = Country::DEFAULT_COUNTRY;
        $user->date_created = time();
        $user->type = Users::TYPE_CUSTOMER;
        $user->status = Users::STATUS_ACTIVE;
        $user->email = $_POST['email'];

        $birthday = ($_POST['birthday'] != '') ? str_replace('/', '-', $_POST['birthday']) : NULL;
        $user->birthday = ($birthday) ? strtotime($birthday) : '';

        if ($user->validate() AND $user->save()) {
            $this->user_id = $user->id;

            if (FALSE == $is_update) {

                $_pass = Utils::genRandomString(7);
                $salt = $user->generateSalt();

                $pass = $user->hashPassword($_pass, $salt);

                $user->salt = $salt;
                $user->password = $pass;
                $user->ukey = $user->genUkey();

                if ($user->save()) {
                    MyEmail::sendToNewUser($user, $_pass);
                } else {
                    MyEmail::send_error('Can not update BooController.php user id' . $user->id);
                }
            }

            return TRUE;
        } else {
            return FALSE;
        }
    }

    public function process_service() {
        $service = Service::getRecordbySid($_POST['service_id']);

        if (NULL == $service) {
            return FALSE;
        } else {
            $this->service = $service;
            return TRUE;
        }
    }

    /**
     * @return mixed <b>FALSE</b> if create fail or <b>a single CACTIVERECORD </b> if success
     */
    public function create_appoinmnet() {

//        submit_checkout:yes
//        service_id:15
//        date:22/Jul/2014
//        staff_time:7_09:00
//        fname:Anh Đức
//        lname:Anh Đức 1
//        email:anhduc.bkhn@gmail.com
//        phone:1234567
//        occupation:Guru at webmaster.com.sg
//        address:477 Minh Khai, Hai Ba trung
//        postal_code:10000
//        birthday:09/Jul/2014
//        note:
        $this->get_staff_id();


        if (FALSE == $this->staff_id)
            return FALSE;

        $appoinmnet = new Appoint();

        $appoinmnet->service_id = $this->service->sid;
        $appoinmnet->date = strtotime(str_replace('/', '-', $_POST['date']));
        $appoinmnet->category_id = $this->service->category_id;
        $appoinmnet->author_id = $this->staff_id; //staff id
        $appoinmnet->type = Appoint::TYPE_APPOINTMENT;
        $appoinmnet->status = Appoint::STATUS_TEMP;
        $appoinmnet->note = $_POST['note'];
        $appoinmnet->start_time = $this->start_time;
        $appoinmnet->end_time = Utils::plusminute($this->start_time, $this->service->duration, $this->service->recover);

        if ($appoinmnet->validate() AND $appoinmnet->save()) {
            $this->appt_id = $appoinmnet->apt_id;
            return $appoinmnet->apt_id;
        } else {
            return FALSE;
        }
    }

    public $order_id = FALSE;
    public $order_date = FALSE;
    public $order_biz = FALSE;
    public $cus_ckey = FALSE;
    public $hotdeal_discount = 0;
    public $biz_id = FALSE;
    public $total_price = FALSE;
    public $init_price = FALSE;
    public $order_key = FALSE;

    /**
     * $this->service, 
     * $this->hotdeal_discount
     * $this->appt_id
     * $this->biz_id
     * $this->cus_ckey,
     * @return boolean
     */
    public function process_order() {

        $order = new Orders();
        $order->apt_id = $this->appt_id;
        $order->biz_id = $this->service->user->id;
        $order->cus_ckey = $this->cus_ckey;
        $order->payment_method = Orders::PAYMENT_PAYPAL;
        $order->hotdeal_discount = $this->hotdeal_discount; // 10, 20 , 4
        $order->status = Orders::STATUS_HOTDEAL;
        $order->order_date = time();
        $order->s_id = $this->service->sid;
        $order->s_price = $this->service->price;
        $order->first_discount=$this->discount_firsttime;
        if ($order->validate() AND $order->save()) {

            $this->order_id = $order->order_id;

            $rkey = $order->genOkey();
            $order->order_key = $rkey;

            if ($order->save()) {
                $this->order_key = $rkey;
                return TRUE;
            } else {
                var_dump($order->getErrors());
                die;

                return FALSE;
            }
        } else {
            var_dump($order->getErrors());
            die;
            return FALSE;
        }
    }

    /**
     * $this->hotdeal_discount
     * $this->init_price
     * $this->total_price
     * $this->order_id
     * 
     * @return boolean
     */
    public function process_receipt() {

        $receipt = new Receipt();
        $receipt->discount = $this->hotdeal_discount; //
        $receipt->discount_type = '%'; //
        $receipt->final_price = $this->total_price; //
        $receipt->list_price = $this->init_price; //init price
        $receipt->order_id = $this->order_id; //
        $receipt->qty = 1; //
        $receipt->receipt_date = time(); //
        $receipt->tax = 0;
        $receipt->item_description = $this->service->description;

        if ($receipt->validate() AND $receipt->save()) {

            $rkey = $receipt->genReceiptKey();

            $receipt->receipt_key = $rkey;

            if ($receipt->save()) {
                return TRUE;
            } else {
                MyEmail::send_error(json_encode($receipt->getErrors()));
                return FALSE;
            }
        } else {
            MyEmail::send_error(json_encode($receipt->getErrors()));
            return FALSE;
        }
    }

    public function get_staff_id() {
        if (!isset($_POST['staff_time'])) {
            return FALSE;
        }

        $staff_time = $_POST['staff_time'];
        $separatedData = explode('_', $staff_time);


        $this->staff_id = $separatedData[0];

        $this->start_time = ltrim($separatedData[1], '0');

        if (FALSE == is_numeric($this->staff_id)) {
            return FALSE;
        }

        return TRUE;
    }

}
